package com.example.other.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.authority.common.entity.MyConst;
import com.example.authority.common.utils.RedisUtil;
import com.example.authority.common.utils.SecurityUtils;
import com.example.authority.mapper.UserMapper;
import com.example.common.enums.OrderStates;
import com.example.other.domain.*;
import com.example.other.domain.dto.OrderQueryParams;
import com.example.other.domain.dto.OrdersDto;
import com.example.other.mapper.*;
import com.example.other.service.OrdersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Limhuang
 * @description 针对表【orders】的数据库操作Service实现
 * @createDate 2024-07-03 10:15:00
 */
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders>
        implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private HospitalMapper hospitalMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealdetailedMapper setmealdetailedMapper;
    @Autowired
    private CheckitemdetailedMapper checkitemdetailedMapper;
    @Autowired
    private CidetailedreportMapper cidetailedreportMapper;
    @Autowired
    private CireportMapper cireportMapper;
    @Autowired
    private UsersInfoMapper usersInfoMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public Orders createOrder(Date date, Integer hpid, Integer smid) {
        // 获取当前用户
        String userid = SecurityUtils.getCurrentUser().getUser().getId().toString();
        Orders orders = new Orders();
        orders.setOrderdate(date);
        orders.setUserid(userid);
        orders.setHpid(hpid);
        orders.setSmid(smid);
        orders.setState(OrderStates.ORDERED.getCode());

        // 检验是否已存在相同订单
        if (ordersMapper.selectList(new QueryWrapper<Orders>().allEq(Map.of(
                "orderDate", date,
                "userId", userid,
                "hpId", hpid,
                "smId", smid,
                "state", OrderStates.ORDERED.getCode()
        ))).size() > 0) {
            throw new RuntimeException("该预约已存在");
        }
        ordersMapper.insert(orders);
        // all meal's check item details
        List<Setmealdetailed> setmealdetailedList = setmealdetailedMapper.selectList(new QueryWrapper<Setmealdetailed>().eq("smId", smid));
        List<Integer> checkitemdetailedIds = new ArrayList<>();
        setmealdetailedList.forEach(setmealdetailed -> {
            checkitemdetailedIds.add(setmealdetailed.getCiid());
        });
        QueryWrapper<Checkitemdetailed> checkitemdetailedQueryWrapper = new QueryWrapper<>();
        checkitemdetailedQueryWrapper.lambda().in(Checkitemdetailed::getCiid, checkitemdetailedIds);
        List<Checkitemdetailed> checkitemdetailedList = checkitemdetailedMapper.selectList(checkitemdetailedQueryWrapper);

        //define a list to store row to insert into cidetailedreport,cireport

        List<Cidetailedreport> cidetailedreportList = new ArrayList<>();
        List<Cireport> cireportList = new ArrayList<>();

        int size = checkitemdetailedList.size();
        for (int i = 0; i < size; i++) {
            Cidetailedreport cidetailedreport = new Cidetailedreport();
            Cireport cireport = new Cireport();
            Checkitemdetailed checkitemdetailed = checkitemdetailedList.get(i);
            cidetailedreport.setCiid(checkitemdetailed.getCiid());
            cidetailedreport.setName(checkitemdetailed.getName());
            cidetailedreport.setUnit(checkitemdetailed.getUnit());
            cidetailedreport.setMinrange(checkitemdetailed.getMinrange());
            cidetailedreport.setMaxrange(checkitemdetailed.getMaxrange());
            cidetailedreport.setNormalvalue(checkitemdetailed.getNormalvalue());
            cidetailedreport.setNormalvaluestring(checkitemdetailed.getNormalvaluestring());
            cidetailedreport.setType(checkitemdetailed.getType());
            cidetailedreport.setOrderid(orders.getOrderid());

            cireport.setCiid(checkitemdetailed.getCiid());
            cireport.setCiname(checkitemdetailed.getName());
            cireport.setOrderid(orders.getOrderid());

            cidetailedreportMapper.insert(cidetailedreport);
            cireportMapper.insert(cireport);

            cidetailedreportList.add(cidetailedreport);
            cireportList.add(cireport);
        }


        return orders;
    }

    /**
     * 取消订单。
     * 通过订单ID查询订单信息，将订单状态更新为已取消，并返回更新后的订单信息。
     *
     * @param id 订单ID，用于唯一标识一个订单。
     * @return 返回更新后的订单信息。
     */
    @Override
    public Orders cancelOrder(String id) {
        // 根据订单ID查询订单
        Orders orders = ordersMapper.selectById(id);

//        Instant orderTime = orders.getOrderdate().toInstant();
//        Instant now = Instant.now();
//        Duration duration = Duration.between(orderTime, now);
//        if (Math.abs(duration.toHours()) <= 24) {
//            throw new RuntimeException("预约在24小时内，无法取消");
//        }

        // 将订单状态设置为已取消/已退款
        if (orders.getState() == OrderStates.ORDERED.getCode()) {
            orders.setState(OrderStates.CANCELLED.getCode());
        } else if (orders.getState() == OrderStates.PAID.getCode()) {
            orders.setState(OrderStates.REFUNDED.getCode());
        }

        // 更新订单状态到数据库
        ordersMapper.updateById(orders);
        // 返回更新后的订单信息
        return orders;
    }

    @Override
    public Map<String, Object> listOrder(OrderQueryParams queryParams) {

        Map<String, Object> result = new HashMap<>();

        // 1.从Redis里取缓存
        String originParams = queryParams.toString();
        String cache = (String) redisUtil.hget(MyConst.ORDER_KEY, originParams);
//        log.warn("查询缓存：{}", cache);
        if (cache != null) {
//            log.warn("缓存不为空：{}",cache);
            result = JSON.parseObject(cache, Map.class);
            return result;
        }

        // 2.没有就查询数据库
        if(queryParams.getState()==null){
//            log.warn("条件查询（无状态）：{}", queryParams);
            // 2.1 同时查询已归档和未归档订单
            result.put("page", queryParams.getPage());
            queryParams.setPage((queryParams.getPage() - 1) * queryParams.getSize());
            result.put("total", ordersMapper.listOrderIgnoreStateCount(queryParams));
            List<OrdersDto> list = ordersMapper.listOrderIgnoreState(queryParams);
            result.put("data", list);
            result.put("size", list.size());
        }else{
//            log.warn("条件查询（有状态）：{}", queryParams);
            // 2.2 条件查询
            result.put("page", queryParams.getPage());
            queryParams.setPage((queryParams.getPage() - 1) * queryParams.getSize());
            result.put("total", ordersMapper.listOrderCount(queryParams));
            List<OrdersDto> list = ordersMapper.listOrder(queryParams);
            result.put("data", list);
            result.put("size", list.size());
        }

//        log.warn("查询数据库：{}", result);
        // 3.存入Redis
        redisUtil.hset(MyConst.ORDER_KEY, originParams, JSON.toJSONString(result));

        return result;
    }

}




